global _ZN5tysos3ABI15OtherOperationsM_0_7ReadCR3_Ry_P0:function
global _ZN5tysos3ABI15OtherOperationsM_0_8WriteCR3_Rv_P1y:function
global _ZN5tysos3ABI15OtherOperationsM_0_7ReadCR2_Ry_P0:function
global _ZN5tysos3ABI15OtherOperationsM_0_8WriteCR2_Rv_P1y:function
global _ZN5tysos3ABI15OtherOperationsM_0_7ReadCR4_Ry_P0:function
global _ZN5tysos3ABI15OtherOperationsM_0_8WriteCR4_Rv_P1y:function
global _ZN5tysos3ABI15OtherOperationsM_0_7ReadCR0_Ry_P0:function
global _ZN5tysos3ABI15OtherOperationsM_0_8WriteCR0_Rv_P1y:function
global _ZN5tysos3ABI15OtherOperationsM_0_4Lidt_Rv_P2yt:function
global _ZN5tysos3ABI15OtherOperationsM_0_3Ltr_Rv_P1y:function
global _ZN5tysos3ABI15OtherOperationsM_0_10WriteMxcsr_Rv_P1j:function
global _ZN5tysos3ABI15OtherOperationsM_0_9ReadMxcsr_Rj_P0:function
global _ZN5tysos3ABI15OtherOperationsM_0_6_Cpuid_Rv_P2jPj:function
global _ZN5tysos3ABI15OtherOperationsM_0_6GetRBP_Ry_P0:function
global _ZN5tysos3ABI15OtherOperationsM_0_5RdMsr_Ry_P1j:function
global _ZN5tysos3ABI15OtherOperationsM_0_5RdTsc_Ry_P0:function
global _ZN5tysos3ABI15OtherOperationsM_0_3Sti_Rv_P0:function
global _ZN5tysos3ABI16MemoryOperationsM_0_19QuickClearAligned16_Rv_P2yy:function

global _ZW6System4MathM_0_5Round_Rd_P1d:function

global __memcpy:function
global __memmove:function

global _conv_u8_r8:function

extern __display_halt
extern __undefined_func

_ZN5tysos3ABI15OtherOperationsM_0_7ReadCR3_Ry_P0:
	mov	rax, cr3
	ret

_ZN5tysos3ABI15OtherOperationsM_0_8WriteCR3_Rv_P1y:
	mov rax, [rsp + 8]
	mov cr3, rax
	ret

_ZN5tysos3ABI15OtherOperationsM_0_7ReadCR0_Ry_P0:
	mov	rax, cr0
	ret

_ZN5tysos3ABI15OtherOperationsM_0_8WriteCR0_Rv_P1y:
	mov rax, [rsp + 8]
	mov cr0, rax
	ret

_ZN5tysos3ABI15OtherOperationsM_0_7ReadCR2_Ry_P0:
	mov	rax, cr2
	ret

_ZN5tysos3ABI15OtherOperationsM_0_8WriteCR2_Rv_P1y:
	mov rax, [rsp + 8]
	mov cr2, rax
	ret

_ZN5tysos3ABI15OtherOperationsM_0_7ReadCR4_Ry_P0:
	mov	rax, cr4
	ret

_ZN5tysos3ABI15OtherOperationsM_0_8WriteCR4_Rv_P1y:
	mov rax, [rsp + 8]
	mov cr4, rax
	ret

_ZN5tysos3ABI15OtherOperationsM_0_4Lidt_Rv_P2yt:
	push rbp
	mov rbp, rsp

	sub rsp, 0x10
	
	mov rax, [rbp + 16]
	mov rbx, rax

	shr rbx, 48
	shl rax, 16
	add rax, [rbp + 24]

	mov [rsp], rax
	mov [rsp + 8], rbx

	lidt [rsp]

	leave
	ret

_ZN5tysos3ABI15OtherOperationsM_0_3Ltr_Rv_P1y:
	ltr [rsp + 8]
	ret

_ZN5tysos3ABI16MemoryOperationsM_0_19QuickClearAligned16_Rv_P2yy:
	push rbp
	mov rbp, rsp

	mov	rdi, [rbp + 16]
	mov rcx, [rbp + 24]

	shr rcx, 4

	sub rsp, 16
	mov rax, 0x0
	mov [rsp], rax
	mov [rsp + 8], rax

	movdqu	xmm0, [rsp]

.doloop:
	movdqa	[rdi], xmm0
	add	rdi, 16
	loop .doloop
	
	leave
	ret
	
__memcpy:
	push rbp
	mov rbp, rsp

	mov rdi, [rbp + 16]
	mov rsi, [rbp + 24]
	mov ecx, [rbp + 32]

	rep movsb

	leave
	ret

__memmove:
	push rbp
	mov rbp, rsp

	mov rdi, [rbp + 16]
	mov rsi, [rbp + 24]
	mov ecx, [rbp + 32]
	
	cmp rdi, rsi
	ja .domove

	rep movsb
	leave
	ret

.domove:
	add rdi, rcx
	add rsi, rcx

	cmp rcx, 0
	jne .doloop

	leave
	ret

.doloop:
	dec rdi
	dec rsi
	
	mov byte al, [rsi]
	mov byte [rdi], al
	loop .doloop

	leave
	ret

_m5_tysos_N3_ABI_T15_OtherOperations_Special_M11_switch_task_S12_0002010F0B0B:
	; return rip is pushed by the call instruction
	pushfq
	push rax
	push rbx
	push rcx
	push rdx
	push rsi
	push rdi
	push rbp
	push r8
	push r9
	push r10
	push r11
	push r12
	push r13
	push r14
	push r15

	; store the old rsp pointer and new rsp value
	mov rbx, [rsp + 144]
	mov rax, [rsp + 136]

	; store the old rsp if the pointer is valid
	cmp rax, 0
	je .dontsave
	mov [rax], rsp
.dontsave:

	; switch to the new stack
	mov rsp, rbx

	; restore saved registers
	pop r15
	pop r14
	pop r13
	pop r12
	pop r11
	pop r10
	pop r9
	pop r8
	pop rbp
	pop rdi
	pop rsi
	pop rdx
	pop rcx
	pop rbx
	pop rax
	popfq

	; ret to restore rip
	ret

_ZN5tysos3ABI15OtherOperationsM_0_6GetRBP_Ry_P0:
	mov rax, rbp
	ret

_ZN5tysos3ABI15OtherOperationsM_0_10WriteMxcsr_Rv_P1j:
	ldmxcsr [rsp + 8]
	ret

_ZN5tysos3ABI15OtherOperationsM_0_9ReadMxcsr_Rj_P0:
	sub rsp, 8
	stmxcsr [rsp]
	mov dword eax, [rsp]
	add rsp, 8
	ret

_ZN5tysos3ABI15OtherOperationsM_0_6_Cpuid_Rv_P2jPj:
	; void _Cpuid(uint req_no, uint *buf)

	xor rcx, rcx
	mov dword eax, [rsp + 8]
	cpuid
	
	mov rdi, [rsp + 16]
	mov dword [rdi], eax
	mov dword [rdi + 4], ebx
	mov dword [rdi + 8], ecx
	mov dword [rdi + 12], edx

	ret

_ZN5tysos3ABI15OtherOperationsM_0_5RdMsr_Ry_P1j:
	; static ulong RdMsr(uint reg_no)
	mov dword ecx, [rsp + 8]
	rdmsr
	sub rsp, 8
	mov dword [rsp], eax
	mov dword [rsp + 4], edx
	mov qword rax, [rsp]
	add rsp, 8
	ret

_ZN5tysos3ABI15OtherOperationsM_0_5RdTsc_Ry_P0:
	rdtsc
	sub rsp, 8
	mov dword [rsp], eax
	mov dword [rsp + 4], edx
	mov qword rax, [rsp]
	add rsp, 8
	ret

_conv_u8_r8:
	push qword [rsp]
	call __undefined_func
	call __display_halt
.haltloop:
	xchg bx, bx
	hlt
	jmp .haltloop

_ZW6System4MathM_0_5Round_Rd_P1d:
	; rely on the mxcsr rounding mode being round-to-even (set up in Arch)

	cvtsd2si	rax, [rsp + 8]
	cvtsi2sd	xmm0, rax

	ret

_ZN5tysos3ABI15OtherOperationsM_0_3Sti_Rv_P0:
	sti
	ret

